<?php

namespace App\Console\Commands\Elasticsearch;

use App\Models\Product;
use Illuminate\Console\Command;

class SyncProducts extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    //添加一个名为index，默认值为products的参数
    protected $signature = 'es:sync-products {--index=products}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '将商品同步到ElasticSearch';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        $es = app('es');
        Product::query()
            //预加载SKu和商品属性数据，避免N+1问题
            ->with(['skus','properties'])
            //使用chunkById避免一次加载过多数据
            ->chunkById(100,function ($products) use ($es){
                 $this->info(sprintf('正在同步ID范围为%s至%s的商品',$products->first()->id,$products->last()->id));

                 //初始化请求体
                $req = ['body' => []];
                //遍历商品
                foreach ($products as $product){
                    //将商品模型转为Elasticsearch所用数组
                    $data = $product->toESArray();

                    $req['body'][] = [
                        'index' => [
                            //从参数中读取索引名称
                            '_index' => $this->option('index'),
                            '_id' => $data['id']
                        ]
                    ];
                    $req['body'][] = $data;
                }

                try{
                    //使用bulk方法批量创建
                    $es->bulk($req);
                }catch (\Exception $e){
                    $this->error($e->getMessage());
                }
            });
        $this->info('同步完成');
    }
}
